﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using FMSpaceShooter.ScreenManager;
using FMSpaceShooter.Screens;
using Microsoft.Xna.Framework.Audio;

namespace FMSpaceShooter.GameObjects
{
    sealed class Player1 : ShipBase
    {
        bool isInPlay = true;
        int lives = 3;
        TimeSpan lastShot = TimeSpan.Zero;
        TimeSpan rateOfFire = TimeSpan.Zero;
        TimeSpan? timeOfDeath = null;
        TimeSpan invulnerableUntil = TimeSpan.Zero;
        bool isInvulnerable = false;
        public int Lives { get { return lives; } }
        public int Bombs { get { return bombCount; } }
        public bool IsInPlay { get { return isInPlay; } }
        public bool IsInvulnerable { get { return isInvulnerable; } }

        private List<string> availableBullets;

        public List<string> AvailableBullets
        {
            get { return availableBullets; }
        }

        private int activeBullet;

        public int ActiveBullet
        {
            get { return activeBullet; }
        }
        




        public Player1(GameplayScreen _screen, string image, Vector2 origin, int health, int numberOfBombs, Vector2 shipSize)
            : base(_screen, image, origin, health, numberOfBombs, shipSize, 480)
        {
            availableBullets = new List<string> { PrimaryBullet.TypeName, SplitterBullet.TypeName, ExplosiveBullet.TypeName};
        }

        public override void Update(GameTime gameTime)
        {
            InputState input = screen.ScreenManager.Input;

            HandleBulletSelection(input);

           
            if (isInPlay)
            {   

                Vector2 motionDirection = Vector2.Zero;
                motionDirection.Y -= input.IsShipUp() ? 1 : 0;
                motionDirection.Y += input.IsShipDown() ? 1 : 0;
                motionDirection.X -= input.IsShipLeft() ? 1 : 0;
                motionDirection.X += input.IsShipRight() ? 1 : 0;

                if (motionDirection != Vector2.Zero)
                {
                    motionDirection.Normalize();

                    position += motionDirection * (float)(speed * gameTime.ElapsedGameTime.TotalSeconds);
                }

                Vector2 tempRotation = (input.CurrentMouseVector - position);
                if (tempRotation != Vector2.Zero)
                {
                    tempRotation.Normalize();
                    rotation = (float)Math.Atan2(tempRotation.X, -tempRotation.Y);
                }

                if (position.X < 0)
                {
                    position.X = 0;
                }
                else if (position.X > ((Game1)screen.ScreenManager.Game).GDM.PreferredBackBufferWidth)
                {
                    position.X = ((Game1)screen.ScreenManager.Game).GDM.PreferredBackBufferWidth;
                }

                if (position.Y < 0)
                {
                    position.Y = 0;
                }
                else if (position.Y > ((Game1)screen.ScreenManager.Game).GDM.PreferredBackBufferHeight)
                {
                    position.Y = ((Game1)screen.ScreenManager.Game).GDM.PreferredBackBufferHeight;
                }

                if (input.IsShipFire())
                {
                    if (lastShot + rateOfFire < gameTime.TotalGameTime)
                    {
                        lastShot = gameTime.TotalGameTime;
                        Vector2 screenCorrection = new Vector2((float)Math.Sin(rotation) * 35, (float)Math.Cos(rotation) * -35);
                        BulletBase bullet = GameData.Factories.BulletFactory(screen, availableBullets[activeBullet], position + screenCorrection, rotation);
                        rateOfFire = TimeSpan.FromMilliseconds(bullet.RateOfFire);
                        screen.GOM.AddToPlay(bullet);
                        screen.AudioManager.PlayFX("AudioFX/bullet1");
                    }
                }
            }
            else if (timeOfDeath == null)
            {
                timeOfDeath = gameTime.TotalGameTime;
                invulnerableUntil = TimeSpan.FromMilliseconds(150 + 40 * 4 + 2000) + gameTime.TotalGameTime;
            }
            else
            {
                var diff = (gameTime.TotalGameTime - (TimeSpan)timeOfDeath).TotalMilliseconds;
                if(diff > 150 + 40 * 4) 
                {
                    isInPlay = true;
                    timeOfDeath = null;
                }
            }
            if (screen.GOM.Negotiator == null)
            {
                isInvulnerable = (invulnerableUntil - gameTime.TotalGameTime).TotalMilliseconds > 0;
            }
            else
            {
                isInvulnerable = true;
            }


            if (screen.ScreenManager.Input.IsDropBomb() && bombCount > 0)
            {
                bombCount--;
                screen.GOM.Negotiator = new Negotiator(screen);
            }
            else if (screen.GOM.Negotiator != null)
            {
                screen.GOM.Negotiator.Update(gameTime);
                if (screen.GOM.Negotiator.IsFinished)
                {
                    screen.GOM.Negotiator.Dispose();
                    screen.GOM.Negotiator = null;
                }
            }
        }

        private void HandleBulletSelection(InputState input)
        {
            
            if (input.IsNewKeyPress(Keys.D1))
            {
                if (activeBullet != 0)
                {
                    activeBullet = 0;
                }
            }
            else if (input.IsNewKeyPress(Keys.D2) && availableBullets.Count > 1)
            {
                if (activeBullet != 1)
                {
                    activeBullet = 1;
                }
            }
            else if (input.IsNewKeyPress(Keys.D3) && availableBullets.Count > 2)
            {
                if (activeBullet != 2)
                {
                    activeBullet = 2;
                }
            }
            else if (input.IsNewKeyPress(Keys.D4) && availableBullets.Count > 3)
            {
                if (activeBullet != 3)
                {
                    activeBullet = 3;
                }
            }
        }

        public override void Draw(GameTime gameTime)
        {
            if (isInPlay)
            {
                BaseDraw(gameTime);
                if (isInvulnerable)
                {
                    //draw a sheild or something
                }
            }
            else if (timeOfDeath != null)
            {
                var diff = (gameTime.TotalGameTime - (TimeSpan)timeOfDeath).TotalMilliseconds;
                if (diff > 1500)
                {
                    if ((int)(diff / 400) % 2 == 1)
                    {
                        BaseDraw(gameTime);
                    }
                }
            }
            // might be a good idea to make a state system for the ship 
        }


        private void BaseDraw(GameTime gameTime)
        {
            SpriteBatch spriteBatch = screen.ScreenManager.SpriteBatch;

            spriteBatch.Draw(texture, position, null, (isInvulnerable ? new Color(155,155,155) : Color.White ),
                rotation, origin, scale, SpriteEffects.None, 0);
        }

        public override void Die()
        {
            if (!isInvulnerable)
            {
                if (lives > 0)
                {
                    isInPlay = false;
                    Vector2 res = new Vector2(screen.GraphicsDeviceManager.PreferredBackBufferWidth,
                        screen.GraphicsDeviceManager.PreferredBackBufferHeight);
                    position = res / 2;
                    rotation = 0;
                    lives--;
                    PrimaryBullet.resetLevel();
                    ExplosiveBullet.resetLevel();
                    SplitterBullet.resetLevel();
                }
                else
                {
                    screen.EndGame();
                }
            }
        }
    }
}
